package programs.expression.implementedClasses;

import java.util.HashSet;
import java.util.Set;

import programs.expression.superClasses.Expression;
import programs.expression.superClasses.ExpressionType;
import game.SpaceObject;

public class Variable extends Expression {
	
	private ExpressionType returnType;
	private final String name;
	private Object value = null;
	
	public Variable(String name, ExpressionType returnType) 
	{
		this.name = name;
		this.returnType = returnType;
		setDefaultValue();
	}
	
	public Variable(String name) {
		this(name, null);
	}

	@Override
	public Set<Variable> getVariables(){
		Set<Variable> set = new HashSet<Variable>();
		set.add(this);
		return set;
	}
	@Override
	public boolean isValidExpression() {
		return isValidNewValue(getValue());
	}

	@Override
	public ExpressionType getReturnType() {
		return this.returnType;
	}
	
	@Override
	public Object getValue() {
		return this.value;
	}
	
	public String getName() {
		return this.name;
	}
	
	public void setValue(Object newValue) 
	{
		if(isValidNewValue(newValue))
			value = newValue;
	}
	
	public boolean isValidNewValue(Object newValue)
	{
		if(getReturnType() == ExpressionType.BOOLEAN)
			return (newValue instanceof Boolean);
		if(getReturnType() == ExpressionType.DOUBLE)
			return (newValue instanceof Double);
		if(getReturnType() == ExpressionType.ENTITY)
			return (newValue == null || newValue instanceof SpaceObject);
		if(getReturnType() == null)
			return true;
		else
			return false;
	}
	
	
	private void setDefaultValue() {
		if(getReturnType() == ExpressionType.BOOLEAN)
			setValue((Boolean) false);
		else if(getReturnType() == ExpressionType.DOUBLE)
			setValue((Double) 0.0);
		else if(getReturnType() == ExpressionType.ENTITY);
			setValue(null);
		
	}

	public void setReturnType(ExpressionType returnType) {
		this.returnType = returnType;
		setDefaultValue();		
	}

	@Override
	public Variable assignGlobalVariable(Variable variable) {
		if(this.getName().equals(variable.getName()))
			return variable;
		else
			return this;
	}

}